package com.xxgc.springboot.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxgc.springboot.config.annotation.RequiresGuest;
import com.xxgc.springboot.entity.Users;
import com.xxgc.springboot.result.Result;
import com.xxgc.springboot.service.IUsersService;
import com.xxgc.springboot.util.JWTUtils;
import com.xxgc.springboot.util.UUIDUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author Mr.Abel
 * @since 2022-09-27
 */
@Slf4j
@RestController
@Api(tags = "用户相关接口")
@RequestMapping("/users")
public class UsersController {

    @Value("${system.md5-key}")
    private String md5Key;

    @Resource
    private IUsersService usersService;

    /**
     * 注册用户
     * @param
     * @return
     */
    @ApiOperation(value = "注册接口", notes = "注册接口")
    @PostMapping("/register")
    public Result register(@RequestBody Users users) {
        //判断用户名是否重复


        //生成一个随机数拼接到key上面（UUID）
        String uuid = UUIDUtils.getUUID(20);
        String myKey = md5Key + uuid;
        users.setSalt(uuid);
        //把密码通过MD5进行加密
        Md5Hash key = new Md5Hash(users.getUpass(), myKey, 2);
        //加密过后再替换原来的明文
        users.setUpass(key.toString());
        usersService.save(users);
        return Result.ok();
    }

    /**
     * Shiro登录接口
     */
    @ApiOperation(value = "用户登录Shiro接口123", notes = "用户登录Shiro接口")
    @PostMapping("/loginShiro")
    @RequiresGuest
    public Result<Map<String,Object>> loginShiro(String userName, String passWord) {
        //通过shiro工具类生成
        //任何能认证的对象
        Subject subject = SecurityUtils.getSubject();
        //封装成Shiro的用户令牌
        UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord);
        log.info("进入登录");
        //登录
        subject.login(token);

        return Result.ok();
    }


    /**
     * 登录接口
     */
    @ApiOperation(value = "用户登录接口", notes = "用户登录接口")
    @PostMapping("/login")
    @RequiresGuest
    public Result<Map<String,Object>> login(String userName, String passWord) {
        Users users = usersService.selectByNameAndPass(userName, passWord);
        if(users == null){
            return Result.error("用户名或密码错误！");
        }
        //通过JWT进行id的加密然后得到token返回给客户端
        Long id = users.getId();
        HashMap<String, String> map = new HashMap<>();
        map.put("id", String.valueOf(id));
        String token = JWTUtils.getToken(map);

        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("token",token);
        map1.put("user",users);
        return Result.ok(map1);
    }

    /**
     * 查询所有接口
     * @return
     */
    @ApiOperation(value = "用户查询所有接口", notes = "查询所有接口")
    @GetMapping
    @RequiresPermissions("users:findAll")
    public Result<List<Users>> findAll() {
        return Result.ok(usersService.list());
    }

    /**
     * 根据id查询数据接口
     * @param id
     * @return
     */
    @ApiOperation(value = "用户查更具id查询", notes = "根据id查询数据接口")
    @GetMapping("/{id}")
    @RequiresPermissions(value = "users:findOne")
    public Result<Users> findOne(@PathVariable Integer id) {
        return Result.ok(usersService.getById(id));
    }

    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "用户分页查询接口", notes = "分页查询接口")
    @GetMapping("/page")
    public Result<Page<Users>> findPage(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        return Result.ok(usersService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }

    /**
     * 新增和更新接口
     * @param
     * @return
     */
    @ApiOperation(value = "用户新增和更新接口", notes = "新增和更新接口")
    @PostMapping
    public Result save(@RequestBody Users users) {
        usersService.saveOrUpdate(users);
        return Result.ok();
    }

    /**
     * 删除接口
     * @param id
     * @return
     */
    @ApiOperation(value = "用户删除接口", notes = "删除接口")
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        usersService.removeById(id);
        return Result.ok();
    }

    /**
     * 批量删除接口
     * @param ids
     * @return
     */
    @ApiOperation(value = "用户批量删除接口", notes = "批量删除接口")
    @PostMapping("/del/batch")
    @RequiresPermissions(value = "users:/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        usersService.removeByIds(ids);
        return Result.ok();
    }
}